package pkg;

import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import com.google.gdata.client.contacts.ContactsService;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.contacts.ContactEntry;
import com.google.gdata.data.contacts.ContactFeed;
import com.google.gdata.data.contacts.ContactGroupEntry;
import com.google.gdata.data.contacts.ContactGroupFeed;
import com.google.gdata.data.extensions.Email;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;

public class Kontakty {
	public Kontakty() {
		serwis = null;
		user = null;
		contactsMap = new HashMap<Integer, ContactEntry>();
		groupsMap = new HashMap<Integer, ContactGroupEntry>();
	}
	public ContactsService serwis;
	public String user;
	private Map<Integer, ContactEntry> contactsMap;
	private Map<Integer, ContactGroupEntry> groupsMap;
	
	public void setUser(String user){
		this.user=user;
	}
	public String getUser(){
		return this.user;
	}
	
	public void setSerwis(ContactsService serwis){
		this.serwis=serwis;
	}
	
	public ContactsService getSerwis(){
		return this.serwis;
	}
	
	public String getContacts(String email, String password){
		String result = null;
		ContactsService serwis = authenticate(email, password);
		if (serwis == null){
			return "<h1>Blad - zly login lub haslo</h1>";
		}
		try{
			result = printAllContacts(serwis,email);
		}
		catch (IOException e){
			return "Blad - IOException";
		}
		catch (ServiceException e){
			return "Blad - ServiceException";
		}
		return result;
	}
	
	// W ContactService przechowywane sa dane połączenia na ich podstawie realizowane sa pozostałe wywołania
	public ContactsService authenticate(String user, String password) {
		serwis = new ContactsService("example");
		this.user = user;
		try {
			serwis.setUserCredentials(user, password);
		} catch (AuthenticationException e) {
			return null;
		}
		return serwis;
	}
	
	/*
	 * createContact tworzy kontakt z podstawowymi danymi tj. Nazwa oraz E-mail
	 */
	public boolean createContact(ContactsService serwis, String name, String email){
		ContactEntry contact = new ContactEntry();
		// dodanie Nazwy kontaktu / mozna dodac takze notatke (setContent)
		contact.setTitle(new PlainTextConstruct(name));
		
		// utworzenie email'a
		Email mail = new Email();
		mail.setAddress(email);		// <- dodanie adresu e-mail
		mail.setPrimary(true);		// <- ustawienie jako glowny podstawowy
		mail.setRel("http://schemas.google.com/g/2005#home"); //<-ustawienie typu
		// dodanie e-mail'a do kontaktu
		contact.addEmailAddress(mail);
		
		/* 
		 * w kontaktach mozna przechowywac wiecej niz jeden adres e-mail 
		 * kolejne maja atrybut setPrimary ustawiony na false
		 */
		try {
			/* cos na rodzaj polaczena z baza danych*/
			URL postURL = new URL("http://www.google.com/m8/feeds/contacts/"+user+"/full");
			serwis.insert(postURL, contact);
		}
		catch (ServiceException e){
			e.printStackTrace();
			return false;
		}
		catch (IOException e){
			e.printStackTrace();
			return false;
		}
		return true;
	}

	// =========================================================
	public String printAllContacts(ContactsService myService, String user)
			throws ServiceException, IOException {
		// URL z danymi coś na rodzaj tabeli w bazie danych
		URL feedUrl = new URL("http://www.google.com/m8/feeds/contacts/" + user
				+ "/full");
		ContactFeed resultFeed = myService.getFeed(feedUrl, ContactFeed.class);
		// Print the results
		StringBuffer out = new StringBuffer();
		out.append("<p align=\"center\">"+resultFeed.getTitle().getPlainText() +"</p>\n");
		out.append("<table BORDER=1>\n");
		out.append("<tr><td>Login</td><td>E-mail</td></tr>");
		contactsMap.clear();
		for (int i = 0; i < resultFeed.getEntries().size(); i++) {
			// Dane jednego kontaktu przechowywane w ponizszej klasie
			ContactEntry entry = resultFeed.getEntries().get(i);
			contactsMap.put(i, entry);
			out.append("<tr\n>");
			out.append("<td>"+(entry.getTitle().getPlainText())+"</td>\n");		// Zwraca Nazwe odbiorcy

			out.append("<td>\n");
			for (Email email : entry.getEmailAddresses()) {
				out.append(" "+(email.getAddress() + " <- " + email.getRel().substring(email.getRel().indexOf("#")+1)) );		// Zwraca kolejne e-maile dla danej osoby

				System.out.print("\n");
			}
			out.append("</td>\n");
			// zmiana kontaktu
			out.append("<td>");
			out.append("<FORM METHOD=POST ACTION=\"kontakty.jsp?zmiana=1\">");
			out.append("<input type=\"hidden\" name=\"poz\" value=\""+i+"\" />");
			out.append("<INPUT TYPE=submit value=\"Zmien\">");
			out.append("</FORM>");
			out.append("</td>");
			
			
			//usuniecie kontaktu
			out.append("<td>");
			out.append("<FORM METHOD=POST ACTION=\"kontakty.jsp?usun=1\">");
			out.append("<input type=\"hidden\" name=\"poz\" value=\""+i+"\" />");
			out.append("<INPUT TYPE=submit value=\"Usun\">");
			out.append("</FORM>");
			out.append("</td>");
			
			out.append("</tr>\n");
		}
		out.append("</table>\n");
		return out.toString();
	}
	
	public boolean deleteContact(ContactsService serwis, ContactEntry contact){
		try {
			// url pobierany jest z kontaktu ktory edytujemy lub usuwamy
			// zdalny serwis poeruje jedynie na url-ach
			URL deleteURL = new URL(contact.getEditLink().getHref());
			serwis.delete(deleteURL);
		}
		catch (ServiceException e){
			return false;
		}
		catch (IOException e){
			return false;
		}
		return true;
	}
	
	public boolean deleteContact(ContactsService serwis, String poz){
		if (poz==null) return false;
		
		int pozycja;
		try {
			pozycja = Integer.parseInt(poz);
			return deleteContact(serwis, contactsMap.get(pozycja));
		}
		catch (NumberFormatException e){
			return false;
		}
	}
	
	public String showContact(ContactsService serwis, String pozycja){
		if (pozycja == null) return "<h2>Bledny wybor</h2>";
		int poz;
		try {
			poz = Integer.parseInt(pozycja);
			return "<h2>Dane:</h2>"+showContact(serwis,contactsMap.get(poz));
		}
		catch (NumberFormatException e){
			return "<h2>Bledny wybor</h2>";
		}
	}
	
	
	public String showContact(ContactsService serwis, ContactEntry contact){
		StringBuffer out = new StringBuffer();
		out.append("<FORM METHOD=POST ACTION=\"kontakty.jsp\">");
		out.append("<TABLE>");
		out.append("<TR>");
		out.append("<TD width = 100>Nazwa:</TD>");
		out.append("<TD><INPUT TYPE=TEXT NAME=username SIZE=20 value=\""+contact.getTitle().getPlainText()+"\"></TD>");
		out.append("</TR>");
		out.append("<TR>");
		out.append("<TD width = 100>E-mail :</TD>");
		out.append("<TD><INPUT TYPE=TEXT NAME=username SIZE=20 value=\""+contact.getEmailAddresses().get(0).getAddress()+"\"></TD>");
		out.append("</TR>");
		out.append("<TR>");
		out.append("<TD width = 100>Grupy :</TD>");
		out.append("<TD><INPUT TYPE=TEXT NAME=username SIZE=20 value=\""+contact.getGroupMembershipInfos()+"\"></TD>");
		out.append("</TR>");
		out.append("<TR>");
		out.append("<TD width = 100>Extended Prop :</TD>");
		out.append("<TD><INPUT TYPE=TEXT NAME=username SIZE=20 value=\""+contact.getExtendedProperties()+"\"></TD>");
		out.append("</TR>");
		out.append("</TABLE>");
		out.append("<INPUT TYPE=submit value=\"Zmien\">");
		out.append("</FORM>");
		
		return out.toString();
	}
	
	public boolean updateContact(ContactsService serwis, String atrybut, ContactEntry contact){
		return true;
	}
	
	
	// ======================================= GRUPY ====================================
	
	public String printAllGroups(ContactsService serwis){
		StringBuffer out = new StringBuffer();
		
		try {
			URL feedURL = new URL("http://www.google.com/m8/feeds/groups/"+user+"/full");
			ContactGroupFeed result = serwis.getFeed(feedURL, ContactGroupFeed.class);
			out.append("<table BORDER=1>\n");
			out.append("<tr><td>ID</td><td>Group Name</td><td>Last Update</td></tr>");
			// wyświetla rezultat
			for (int i=0; i<result.getEntries().size(); i++){
				out.append("<tr>\n");
				ContactGroupEntry entry = result.getEntries().get(i);
				groupsMap.put(i, entry);
				
				out.append("<td>"+(i+1)+"</td>\n");
				out.append("<td>"+entry.getTitle().getPlainText()+"</td>\n");
				out.append("<td>"+entry.getUpdated()+"</td>\n");
				//out.append("<td>"+entry+"</td>\n");
				
				// zmiana grupy
				out.append("<td>");
				out.append("<FORM METHOD=POST ACTION=\"kontakty.jsp?grupa_zmiana=1\">");
				out.append("<input type=\"hidden\" name=\"poz\" value=\""+i+"\" />");
				out.append("<INPUT TYPE=submit value=\"Zmien\">");
				out.append("</FORM>");
				out.append("</td>");
				
				
				//usuniecie grupy
				out.append("<td>");
				out.append("<FORM METHOD=POST ACTION=\"kontakty.jsp?grupa_usun=1\">");
				out.append("<input type=\"hidden\" name=\"poz\" value=\""+i+"\" />");
				out.append("<INPUT TYPE=submit value=\"Usun\">");
				out.append("</FORM>");
				out.append("</td>");
				
				out.append("</tr>\n");
			}
			out.append("</table>");
			return out.toString();
		}
		catch (ServiceException e){
			return "<h2>Blad</h2>";
		}
		catch (IOException e){
			return "<h2>Blad</h2>";
		}
	}
	
	public boolean insertNewContactGroup(ContactsService serwis, String name){
		ContactGroupEntry group = new ContactGroupEntry();
		// ustawienie nazwy grupy
		group.setTitle(new PlainTextConstruct(name));
		
		// dodanie nowej grupy do serwisu googl'a
		try {
			URL postURL = new URL("http://www.google.com/m8/feeds/groups/"+user+"/full");
			serwis.insert(postURL, group);
		}
		catch (ServiceException e){
			return false;
		}
		catch (IOException e){
			return false;
		}
		return true;
	}
	
	public boolean updateContactGroup(ContactsService serwis, String name){
		return true;
	}
	
	public boolean deleteContactGroup(ContactsService serwis, String pozGrp){
		if (pozGrp == null) return false;
		try{
			int pozycja = Integer.parseInt(pozGrp);
			return deleteContactGroup(serwis,groupsMap.get(pozycja));
		}
		catch (NumberFormatException e){
			return false;
		}
	}
	
	public boolean deleteContactGroup(ContactsService serwis, ContactGroupEntry group){
		try {
			URL deleteURL = new URL(group.getEditLink().getHref());
			serwis.delete(deleteURL);
			return true;
		}
		catch (ServiceException e){
			return false;
		}
		catch (IOException e){
			return false;
		}
	}
}
